import { defineStore } from 'pinia';
import Taro from '@tarojs/taro';
import { ref, reactive, onMounted, watch } from 'vue';

export const useBluetoothStore = defineStore('bluetooth', () => {

  // ArrayBuffer 转 16 进制字符串的函数
  
  // const ab2hex = (buffer) => {
  //   const hexArr = Array.prototype.map.call(new Uint8Array(buffer), bit => ('00' + bit.toString(16)).slice(-2))
  //   return hexArr.join('')
  // }

  function ab2hex(buffer) {
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function(bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  }
  // ab2hex(device.advertisData)) 解析后是 fe06010302243030c1f3bdf1f50cad3b65ca3cea0000111c
  function getUniqueId(bf) {
      let buffer = bf.slice(4, 10);
      let hexArr = Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
      return hexArr.toUpperCase()
  }

  // 将字符串转换成ArrayBufer
  const string2buffer = (str) => {
    let val = ""
    if(!str) return;
    let length = str.length;
    let index = 0;
    let array = []
    while(index < length){
      array.push(str.substring(index,index+2));
      index = index + 2;
    }
    val = array.join(",");
    // 将16进制转化为ArrayBuffer
    return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    })).buffer
  }

  // 查找数组中的元素
  const inArray = (arr, key, val) => {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i][key] === val) {
        return i
      }
    }
    return -1
  }

//   let discoveryStarted = false
  // 数据管理
  const state = reactive({
    discoveryStarted:false, // 是否扫描
    devices: [],           // 蓝牙搜索到所有设备的列表
    connected: false,      // 是否链接
    isScan: false,
    chs: [],
    name: '',               
    canWrite: false,        // 是否写入
    deviceId: '',           // 设备ID
    serviceId: '',          // 设备服务ID
    characteristicId: '',   // uuid 可能为读取、写入、订阅
    filterName: '',         // 筛选设备的名称
    penListData: [],        // 筛选后的设备列表
    readId:'',              // 读取的uuid
    writeId: '',            // 写入的uuid
    notifyId: '',           // 订阅的uuid
    wifiStatus: 0,          // wifi状态
    electricity: 0,         // 电量状态
    mac: '',
    sn: '',
    shouldAppend: true ,     // 是否需要拼接
    wifiList: [],
    isFinishWifiList: false, // 是否查找到wifi列表
    chooseWifiName: '',
    index: 0,                // 新增的 index 状态 用于绑定页面的状态 bind页面
    pageStatus:0,            // 新增的 index 状态 用于绑定页面的状态 wifilink页面
    // isChooseWifi: false
    isInoffering: false ,     // 是否在作品页
    hasExecuted: false ,      // 蓝牙查找设备时，只执行一次的标志
    lastConnectedDevice: '',   // 记录最后一次连接蓝牙的deviceId
    fromPage: ''
  })

  const resetState = () => {
    state.discoveryStarted = false;
    state.devices = [];
    state.connected = false;
    state.isScan = false;
    state.chs = [];
    state.name = '';
    state.canWrite = false;
    state.deviceId = '';
    state.serviceId = '';
    state.characteristicId = '';
    state.filterName = '';
    state.penListData = [];
    state.readId = '';
    state.writeId = '';
    state.notifyId = '';
    state.wifiStatus = 0;
    state.electricity = 0;
    state.mac = '';
    state.sn = '';
    state.shouldAppend = true;
    state.wifiList = [];
    state.isFinishWifiList = false;
    state.chooseWifiName = '';
    state.index = 0;
    state.pageStatus = 0;
    state.isInoffering = false
    state.hasExecuted = false
    state.lastConnectedDevice = ''
    state.fromPage = ''
  };

  const setStateIndex = (newIndex) => {
    state.index = newIndex
    console.log('state.index 已更新为:', state.index)
  }

  // 打开蓝牙适配器
  const openBluetoothAdapter = () => {
    
    try {
      Taro.openBluetoothAdapter({
        success: (res) => {
          console.log('打开蓝牙适配器 - openBluetoothAdapter success:', res)
          startBluetoothDevicesDiscovery()
        },
        fail: (res) => {
          setTimeout(() => {
            Taro.showToast({
              title: '请检查蓝牙是否已开启',
              duration: 2000
            })
          },1000)
          if (res.errCode === 10001) {
            Taro.onBluetoothAdapterStateChange((res) => {
              console.log('打开蓝牙适配器 - openBluetoothAdapter失败中的 onBluetoothAdapterStateChange:', res)
              if (res.available) {
                startBluetoothDevicesDiscovery()
              }
            })
          }
        }
      })
    } catch(err) {
      setTimeout(() => {
        Taro.showToast({
          title: '请检查蓝牙是否已开启',
          duration: 2000
        })
      },1000)
    }
    
  }

  // 获取蓝牙适配器状态
  const getBluetoothAdapterState = (type) => {
    Taro.getBluetoothAdapterState({
      success: (res) => {
        console.log('获取蓝牙适配器状态 - getBluetoothAdapterState - success.res', res)

        if (type) return
        if (res.discovering) {
          onBluetoothDeviceFound()
          // getBluetoothDevices
        } else if (res.available) {
          startBluetoothDevicesDiscovery()
        }

        
      }
    })
  }

  // 开始扫描蓝牙设备
  const startBluetoothDevicesDiscovery = () => {
    if (state.discoveryStarted) return
    state.discoveryStarted = true
    Taro.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: true,
      success: (res) => {
        console.log(' 开始扫描蓝牙设备 - startBluetoothDevicesDiscovery - success回调结果res为：', res)
        onBluetoothDeviceFound()
        // getBluetoothDevices
      },
    })
  }

  // 停止扫描蓝牙设备
  const stopBluetoothDevicesDiscovery = () => {
    Taro.stopBluetoothDevicesDiscovery()
    Taro.offBluetoothDeviceFound()
    console.log('stopBluetoothDevicesDiscoveryー停止扫描')
    count = 0
  }

  let count = 0
  // 蓝牙设备发现时的回调   onBluetoothDeviceFound
  const onBluetoothDeviceFound = () => {
    Taro.onBluetoothDeviceFound((res) => {
      console.log('蓝牙设备发现时的回调 - onBluetoothDeviceFound -res.devices:::::', ...res.devices)
      // if (state.penListData.length) return
      res.devices.forEach(device => {
        if (!device.name && !device.localName) return
        console.log('搜索了',++count, '次')
        console.log('蓝牙设备发现时的回调 - device::', device.advertisData)
        console.log('==================================================================')
        // console.log('蓝牙设备发现时的回调 - ab2hex(device.advertisData):', ab2hex(device.advertisData))  // fe06010302243030c1f3bdf1f50cad3b65ca3cea0000111c
        console.log('getUniqueId:', ab2hex(device.advertisData)) 
        console.log('================================================================= =')

        const foundDevices = state.devices
        const idx = inArray(foundDevices, 'deviceId', device.deviceId)
        console.log('deviceData:', device)

        const json = {}
        json.nickName = device.name
        json.deviceId = device.deviceId
        json.rssi = device.RSSI

        if (idx === -1) {
          state.devices.push(device)
        } else {
          state.devices[idx] = device
        }
      })

      // 更新筛选后的设备列表
      // filterDevices();
      console.log('是否切换设备 - state.isInoffering：', state.isInoffering)
      if (!state.isInoffering) {  // 当没有切换设备的时候筛选设备名称
        filterDevices();
      }
      onDiscoverBluetoothDevices()
    })
  }


  function onDiscoverBluetoothDevices() {
    console.log('state.penListData.length:', state.penListData.length)
    console.log('state.hasExecuted:', state.hasExecuted)
    if (state.hasExecuted) return; // 如果已经执行过，直接返回
    state.hasExecuted = true; // 设置标志位，确保只执行一次

    setTimeout(() => {  
      if(state.penListData.length) {
        state.index = 3;
        stopBluetoothDevicesDiscovery(); // 执行停止蓝牙搜索的逻辑
      }
    }, 5000);

    setTimeout(() => {  
      if (!state.penListData.length && !state.isInoffering) {
        console.log('未查找到设备，请重新查找')
        Taro.showToast({
          title: '未查找到设备，请重新查找',
          icon: 'error',
          duration: 3000
        })
        stopBluetoothDevicesDiscovery(); // 执行停止蓝牙搜索的逻辑
        resetState()
        state.index = 0;
      }
    }, 6000);
  }


  // 筛选设备名称
  const setFilterName = (name) => {
    state.filterName = name;
    // filterDevices();
  };

  // 过滤设备列表
  const filterDevices = () => {
    console.log('Current - 打印所有设备 - devices:', state.devices);
    console.log('Current - 打印当前筛选名称 - filterName:', state.filterName);

    if (state.filterName) {
        const filterName = String(state.filterName).toLowerCase();

        // 清空 penListData，以确保只保留当前筛选的设备
        const filteredDevices = state.devices.filter(device => {
            let nickName = String(device.name || device.localName || '');
            console.log('检查设备名称 - Checking device:', nickName);

            // 判断设备名称是否包含 filterName
            const match = nickName.toLowerCase().includes(filterName);
            console.log('匹配状态 - match:', match);

            return match;  // 仅返回包含 filterName 的设备
        }).map(device => {
            // 仅保留符合条件的设备，并替换名称
            return {
                nickName: (String(device.name || device.localName || '').replace(new RegExp(filterName, "i"), "智能毛笔")),  // 替换名称
                deviceId: device.deviceId,
                rssi: device.RSSI
            };
        });

        // 将筛选出来的设备追加到 penListData，避免重复添加
        filteredDevices.forEach(newDevice => {
            const exists = state.penListData.some(device => device.deviceId === newDevice.deviceId);
            if (!exists) {
                state.penListData.push(newDevice);
            }
        });

        console.log('筛选后的列表 - penListData:', state.penListData);

    } else {
        console.log('没有筛选条件 - 未修改 penListData');
    }

};


  Taro.getSystemInfo({
    success: function (res) {
      if (!res.bluetoothEnabled) {
        Taro.showToast({
          title: '请先打开蓝牙再重试',
          icon: 'none',
          duration: 3000
        });
      }
    }
  });

  // 创建蓝牙连接
  const createBLEConnection = (deviceId, name) => {
    console.log('创建蓝牙连接 - 传入参数 - deviceId:', deviceId)
    console.log('创建蓝牙连接 - 传入参数 - name:', name)
    Taro.createBLEConnection({
      deviceId,
      success: () => {
        state.connected = true
        state.name = name
        // state.deviceId = deviceId
        state.mac = deviceId 

        // 保存deviceId（40:47:06:79:66:c2）形式， 切换设备时用此deviceId来断开
        Taro.setStorageSync('lastConnectedDevice', deviceId);
        state.lastConnectedDevice = deviceId
        console.log('创建',name,'蓝牙连接时存入的deviceId', deviceId)


        getBLEDeviceServices(deviceId)
      },
      fail:() => {
        console.log('创建蓝牙连接失败')
        Taro.hideLoading();
        state.connected = false
        if (!state.isInoffering) {
          state.index = 2
          stopBluetoothDevicesDiscovery();
        }
        
      }
    })
    // stopBluetoothDevicesDiscovery()
  }


  // 关闭蓝牙连接
  const closeBLEConnection = () => {
    console.log('关闭蓝牙连接')
    Taro.closeBLEConnection({
      // deviceId: state.deviceId
      deviceId: state.mac
    })
    state.connected = false
    state.chs = []
    state.canWrite = false
    state.penListData = []
  }

  // 关闭蓝牙适配器
  const closeBluetoothAdapter = () => {
    console.log('关闭蓝牙适配器 - closeBluetoothAdapter')
    Taro.closeBluetoothAdapter()
    state.discoveryStarted = false
  }

  // 获取蓝牙设备的服务
  const getBLEDeviceServices = (deviceId) => {
    console.log('获取蓝牙设备的服务传入参数-deviceId:', deviceId)
    Taro.getBLEDeviceServices({
      deviceId,
      success: (res) => {
        console.log('获取蓝牙设备的服务-getBLEDeviceServices.success:res', res)
        for (let i = 0; i < res.services.length; i++) {
          if (res.services[i].isPrimary) {
            getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
            return
          }
        }
      }
    })
  }

  // 获取蓝牙设备的特征值
  const getBLEDeviceCharacteristics = (deviceId, serviceId) => {
    console.log('获取蓝牙设备的特征值传入 - deviceId:', deviceId)
    console.log('获取蓝牙设备的特征值传入 - serviceId:', serviceId)
    Taro.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        console.log('获取蓝牙设备的特征值-getBLEDeviceCharacteristics方法-回调结果res.characteristics为：', res.characteristics)

        res.characteristics.forEach(item => {
          // 该特征支持读取 
          if (item.properties.read && item.uuid.startsWith('00001803')) {
            console.log( 'if (item.properties.read) - item.uuid', item.uuid)
            state.readId = item.uuid
            state.characteristicId = item.uuid
            Taro.readBLECharacteristicValue({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
            })
          }

          // 该特征支持写入
          if (item.properties.write) {
            console.log( 'if (item.properties.write) - item.uuid:', item.uuid ) 
            console.log('state.canWrite 改变前应该为false' , state.canWrite)
            state.canWrite = true
            // state.deviceId = deviceId
            state.mac = deviceId
            state.serviceId = serviceId
            state.characteristicId = item.uuid
            state.writeId = item.uuid
            writeBLECharacteristicValue([0x01]) // 获取设备信息
            console.log('item.properties.write - 获取设备信息')
            writeBLECharacteristicValue([0x02]) // 获取设备状态
            console.log('item.properties.write - 获取设备状态')
          }

          // 该特征支持写入 通知 或者 指示
          if(item.properties.notify || item.properties.indicate) {
            console.log( 'if (item.properties.notify || item.properties.indicate){}',  item.uuid)
            state.notifyId = item.uuid
            Taro.notifyBLECharacteristicValueChange({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
              state: true,
            })
          }
        })
      },
      fail(res) {
        console.error('getBLEDeviceCharacteristics失败的回调:', res)
      }
    })

    // 监听特征值变化
    Taro.onBLECharacteristicValueChange((res) => {
      console.log('监听特征值变化 - onBLEresValueChange - 回调结果为res', res)

      const data = res.value;
      console.log('特征值变化', data);

      getDeviceInfo(res) // 获取设备信息

    })
  }

  // 构建获取设备基本信息的请求数据包
  const buildRequestPacket = (num) => {
    const header = [0x31, 0xaa, 0x55]; // 帧头
    const version = [0x00]; // 版本
    const flag = [0x00]; // 消息标志
    const command = num;
    const errorFlag = [0x00]; // 错误标志
    const dataLength = [0x00, 0x00]; // 数据长度为 0
    const checksum = [(header[1] + header[2] + version[0] + flag[0] + command[0] + errorFlag[0] + dataLength[0] + dataLength[1]) % 256]; // 校验和
    return new Uint8Array([...header, ...version, ...flag, ...command, ...errorFlag, ...dataLength, ...checksum]).buffer;
  };


  // 写入蓝牙特征值
  const writeBLECharacteristicValue = (num) => {
    Taro.writeBLECharacteristicValue({
      // deviceId: state.deviceId,
      deviceId: state.mac,
      serviceId: state.serviceId,
      characteristicId: state.writeId,
      value: buildRequestPacket(num),
      success() {
        console.log('writeBLECharacteristicValue写入成功')
      }
    })
  }

  let bufferCache = new Uint8Array(); // 使用 Uint8Array 来缓存接收到的字节

  // 获取设备状态
  function getDeviceStatus(res) {
  const value = res.value; 
    // 使用 Uint8Array 读取二进制数据
    let byteArray = new Uint8Array(value); 
    // decode(byteArray) 
  }

  // 读取设备信息
  // 初始化缓存数组
  function getDeviceInfo(res) {
    console.log('state.shouldAppend::', state.shouldAppend);
    const value = res.value;

    // 使用 Uint8Array 读取二进制数据
    let byteArray = new Uint8Array(value);
    console.log('byteArray::', byteArray);

    // 检查包头是否为 0x30 或 0x31
    if (byteArray[0] === 0x30) {
        // 根据 state.shouldAppend 决定是否继续拼接
        if (state.shouldAppend) {
            // 去掉第一个字节，继续拼接
            byteArray = byteArray.slice(1);

            const combinedBuffer = new Uint8Array(bufferCache.length + byteArray.length);
            combinedBuffer.set(bufferCache, 0);
            combinedBuffer.set(byteArray, bufferCache.length);
            bufferCache = combinedBuffer;

            console.log('bufferCache::', bufferCache); 
        } else {
            console.log('跳过拼接操作');
        }
    } else if (byteArray[0] === 0x31) {
        // 如果包头为 0x31，去掉第一个字节并结束拼接
        byteArray = byteArray.slice(1);

        // 将最后一包数据添加到缓存
        const finalBuffer = new Uint8Array(bufferCache.length + byteArray.length);
        finalBuffer.set(bufferCache, 0);
        finalBuffer.set(byteArray, bufferCache.length);

        console.log('最终拼接的数据:', finalBuffer);

        // 解析最终数据
        decode(finalBuffer);

        // 清空缓存
        bufferCache = new Uint8Array();
        return;
    }
  }

  // 读取设备状态
  function setDeviceStatus(uint8Array) {
    
    const dataView = new DataView(uint8Array.buffer);
    // 解码数据部分

    const wifi = dataView.getInt8(8);
    const electricity = dataView.getInt8(9);

    console.log('wifi:', wifi)
    console.log('electricity:', electricity)

    return {
      wifiStatus: wifi, 
      electricityStatus: electricity
    }
  }

  const wifiLinkStatus = (status) => {
    const statusMessages = {
      0: '没有配置ssid密码',
      1: '没有连接上',
      2: '连接上了',
      3: '连接上服务器',
      4: '服务器地址错误',
      5: 'token获取失败',
      6: '获取时间戳失败',
      7: '上传图片失败 '
    }
    return statusMessages[status]
  }

  let wifiListCache = [];

  function decode(uint8Array) {
    const dataView = new DataView(uint8Array.buffer);

    // getUint16 读取的是 2 字节无符号整数，可选大小端字节序。
    // getInt8 读取的是 1 字节有符号整数，只有大端序
    // getUint16(0, true) 第二个参数为true时是 小端字节序（little-endian）在小端字节序中，低位字节放在内存的低地址处（即字节顺序是“从小到大”存储）。
    const head = dataView.getUint16(0, true); // 读取 head
    const ver = dataView.getInt8(2); // 版本
    const seqNo = dataView.getInt8(3); // message mark
    const cid = dataView.getInt8(4); // command ID
    const reFlag = dataView.getInt8(5); // error mark
    const len = dataView.getUint16(6, true); // 数据长度
    console.log("============================================================================================");
    console.log("头部 - 读取 head:", head);
    console.log("头部 - ver版本:", ver);
    console.log("头部 - message mark:", seqNo);
    console.log("头部 - command ID:", cid);
    console.log("头部 - error mark:", reFlag);
    console.log("头部 - 数据长度:", len);
    console.log("============================================================================================");

    if (cid === 1) { //读取设备信息
      console.log('cid:1 - 读取设备信息')
      // 解码数据部分
      const vendor = String.fromCharCode.apply(null, uint8Array.slice(8, 17)).replace(/\u0000/g, '');
      const product = String.fromCharCode.apply(null, uint8Array.slice(17, 26)).replace(/\u0000/g, '');
      const version = String.fromCharCode.apply(null, uint8Array.slice(26, 34)).replace(/\u0000/g, '');
      const devid = String.fromCharCode.apply(null, uint8Array.slice(34, 47)).replace(/\u0000/g, '');
      const devname = String.fromCharCode.apply(null, uint8Array.slice(47, 77)).replace(/\u0000/g, '');
      const sn = String.fromCharCode.apply(null, uint8Array.slice(77, 109)).replace(/\u0000/g, '');
      // 输出信息

      
      console.log("============================================================================================");
      console.log("产商:", vendor);
      console.log("产品:", product);
      console.log("版本号:", version);
      console.log("设备ID:", devid);
      console.log("设备名称:", devname);
      console.log("序列号sn:", sn);
      console.log("============================================================================================");
      // state.mac = devid;
      state.deviceId = devid;
      state.sn = sn;
      console.log('state.deviceId:', state.deviceId)
      console.log('state.sn:', state.sn)

      if(!state.sn) {
        Taro.showToast({
          title: '绑定失败，请从新绑定',
          icon: 'error',
          duration: 3000
        })
        setTimeout(() => {
          state.pageStatus = 0 
        },3500)
      }

    }

    if (cid === 2) { //读取设备状态
      console.log('cid:2 - 读取设备状态')
      // getDeviceStatus(res)
      // setDeviceStatus(uint8Array)
      // const dataView = new DataView(uint8Array.buffer);
      // 解码数据部分
      const wifi = dataView.getInt8(8);
      const electricity = dataView.getInt8(9);
      console.log('wifi:', wifi)
      console.log('electricity:', electricity)
      return {
        wifiStatus: wifi, 
        electricityStatus: electricity
      }
    }

    if (cid === 3) { //当设备状态变化时通知
      console.log('cid:3 - 当设备状态变化时通知')
      
      const wifi = dataView.getInt8(8);
      const electricity = dataView.getInt8(9);
      console.log('wifi', wifi)
      console.log('wifistatus:', wifiLinkStatus(wifi))
      console.log('electricity:', electricity)
      state.wifiStatus = wifi
      state.electricity = electricity

      // 0: '没有配置ssid密码',
      // 1: '没有连接上',
      // 2: '连接上了',
      // 3: '连接上服务器',
      // 4: '服务地址错误',
      // 5: 'token获取失败',
      // 6: '获取时间戳失败',
      // 7: '上传图片失败 '

      // 当wifi列表已经完成接收的状态下
      if ( state.isFinishWifiList ) {

        if (wifi === 3  || wifi >= 6) {  //  配网成功
          state.pageStatus = 3           //  跳转至配网成功页面
        }

        if(wifi === 0  || wifi === 1) {  //  wifi设置错误
          state.pageStatus = 0           //  跳转至输入wifi名与密码页面
          Taro.showToast({
            title: 'wifi设置错误',
            icon: 'error',
            duration: 3000
          })
        }

        if(wifi === 2) {
          // 继续等待别的状态
        }

        if(wifi === 4) {         // 服务器连接失败
          state.pageStatus = 2   //  跳转至重新连接页面
          Taro.showToast({
            title: '服务器连接失败',
            icon: 'error',
            duration: 3000
          })
        }

        if(wifi === 5) {         // 设备认证失败
          state.pageStatus = 2   //  跳转至重新连接页面
          Taro.showToast({
            // title: wifiLinkStatus(wifi),
            title: '设备认证失败',
            icon: 'error',
            duration: 3000
          })
        }
      }
      
    }

    if (cid === 4) {    //wifi列表
      console.log('cid:4 - wifi列表')
      // 缓存接收到的 Wi-Fi 列表数据

      const isLastPacket = dataView.getInt8(8);

      const ssid = decodeUTF8Manually(String.fromCharCode.apply(null, uint8Array.slice(9, 42)).replace(/\u0000/g, ''));
      
      // 读取加密方式、信道和信号强度
      const encryptionType = dataView.getInt8(42);    // 加密方式，1字节 - 0，不加密，1加密的
      const channel = dataView.getInt8(43);            // 信道，1字节 - 1-13
      const signalStrength = dataView.getInt8(44);     // 信号强度，1字节 - 范围是-100到0

      console.log('isLastPacket:', isLastPacket)
      console.log('ssid:', ssid)
      console.log('encryptionType:', encryptionType)
      console.log('channel:', channel)
      console.log('signalStrength:', signalStrength)

      let json = {}
      if(ssid) {
        json.ssid = ssid
        json.encryptionType = encryptionType
        json.channel = channel
        json. signalStrength =  signalStrength
        state.wifiList.push(json)
      }

      if (isLastPacket !== 0) {
        state.isFinishWifiList = true
        console.log('state.wifiList:', state.wifiList)
      }

      
      // processWifiListResponse(uint8Array);

      // console.log('wifiListCache:', wifiListCache)
          
    }

    if (cid === 5) { //连接Wi-Fi的返回数据
      console.log('cid:5 - 连接Wi-Fi的返回数据')
      setTimeout(() =>{
        writeBLECharacteristicValue([0x02]) // 获取设备状态
      },10000)
    }
  
  }

  
    // 解析接收的 Wi-Fi 数据包
    function processWifiListResponse(byteArray) {

      console.log('判断是否是最后一包:', byteArray[0], byteArray[0] === 0x31)

      // 判断是否是最后一包
      const isLastPacket = byteArray[0] === 0x31;
      
      // 获取SSID，33字节
      const ssidBytes = byteArray.slice(1, 34);
      let ssid = '';
      for (let i = 0; i < ssidBytes.length; i++) {
          if (ssidBytes[i] === 0) break; // 遇到空字节时停止
          ssid += String.fromCharCode(ssidBytes[i]);
      }
  
      // 读取加密方式、信道和信号强度
      const encryptionType = byteArray[34];     // 加密方式，1字节
      const channel = byteArray[35];            // 信道，1字节
      const signalStrength = byteArray[36];     // 信号强度，1字节
  
      // 保存 Wi-Fi 信息到列表缓存中
      wifiListCache.push({
          ssid,
          encryptionType,
          channel,
          signalStrength
      });
  
      // 如果是最后一包，完成 Wi-Fi 列表接收并显示
      if (isLastPacket) {
          console.log("Wi-Fi 列表接收完毕:", wifiListCache);
          // 这里可以执行后续操作，例如更新页面显示
      }
    }


    function decodeUTF8Manually(str) {
      // 将每个字符转换成字节数组
      const byteArray = [];
      for (let i = 0; i < str.length; i++) {
        const charCode = str.charCodeAt(i);
        byteArray.push(charCode & 0xff); // 取低 8 位
      }
    
      // 将字节数组重新转换为 UTF-8 字符串
      try {
        return decodeURIComponent(byteArray.map(b => '%' + b.toString(16).padStart(2, '0')).join(''));
      } catch (e) {
        console.error("解码失败:", e);
        return str; // 如果失败，返回原始字符串
      }
    }

  // =====================  构建数据帧函数与分片发送 ================================================================================

  // 构建数据帧函数
  const buildWifiFrame = (ssid, password, domain) => {
    const frameHeader = [0x31, 0xaa, 0x55]; // 帧头
    const version = 0x00;                   // 版本
    const messageFlag = 0x00;               // 消息标志
    const commandWord = 0x05;               // 命令字
    const errorFlag = 0x00;                 // 错误标志
  
    // 将字符串转换为字节数组，并确保符合长度要求
    const stringToBytes = (str, length) => {
      const bytes = [];
      for (let i = 0; i < length; i++) {
        bytes.push(i < str.length ? str.charCodeAt(i) : 0x00);
      }
      return bytes;
    };
  
    const ssidBytes = stringToBytes(ssid, 33);      // 截取前 33 字节
    const passwordBytes = stringToBytes(password, 33);
    const domainBytes = stringToBytes(domain, 30);
  
    // 构造数据字段
    const data = [...ssidBytes, ...passwordBytes, ...domainBytes];
    const dataLength = data.length;
    const dataLengthBytes = [(dataLength >> 8) & 0xff, dataLength & 0xff]; // 高低字节表示数据长度
  
    // 构建数据帧（除校验和）
    const frame = [
      frameHeader[1],
      frameHeader[2],
      version,
      messageFlag,
      commandWord,
      errorFlag,
      ...dataLengthBytes,
      ...data
    ];
  
    // 计算校验和并添加到数据帧中
    const checksum = frame.reduce((sum, byte) => sum + byte, 0) % 256;
    frame.push(checksum);
  
    return frame;
  };

  // 蓝牙发送分包函数
  const sendWifiFrameToModule = async (frame) => {
    // const deviceId = state.deviceId;            // 已连接设备的 deviceId
    const deviceId = state.mac;                    // 已连接设备的 deviceId
    const serviceId = state.serviceId;             // 服务的 UUID
    const characteristicId = state.writeId;        // 写入特征值的 UUID
    const maxChunkSize = 20;                       // 每个数据包最大 20 字节
    let isEnd = false;

    for (let i = 0; i < frame.length; i += maxChunkSize - 1) {
      // 构造单个数据包
      const chunk = frame.slice(i, i + maxChunkSize - 1);
      isEnd = (i + maxChunkSize - 1 >= frame.length); // 是否是最后一个包

      // 包头标记：0 表示未结束，1 表示结束
      const packet = [isEnd ? 0x31 : 0x30, ...chunk];
      const buffer = new ArrayBuffer(packet.length);
      const dataView = new DataView(buffer);

      // 将数据填充到 buffer 中
      packet.forEach((byte, index) => dataView.setUint8(index, byte));

      try {
        // 使用 Taro.writeBLECharacteristicValue 发送数据包
        await Taro.writeBLECharacteristicValue({
          deviceId,
          serviceId,
          characteristicId,
          value: buffer
        });
        console.log(`成功发送数据包`, packet);
      } catch (err) {
        console.error(`发送数据包失败`, err);
        break; // 如果发送失败，停止发送
      }
    }
  };

  return {
    state,
    setStateIndex,
    string2buffer,
    ab2hex,
    getDeviceStatus,
    openBluetoothAdapter,               // 打开蓝牙适配器
    getBluetoothAdapterState,           // 获取蓝牙适配器状态
    startBluetoothDevicesDiscovery,     // 开始扫描蓝牙设备
    stopBluetoothDevicesDiscovery,      // 停止扫描蓝牙设备
    onBluetoothDeviceFound,             // 蓝牙设备发现时的回调
    createBLEConnection,                // 创建蓝牙连接
    closeBLEConnection,                 // 关闭蓝牙连接
    getBLEDeviceServices,               // 获取蓝牙设备的服务
    getBLEDeviceCharacteristics,        // 获取蓝牙设备的特征值
    writeBLECharacteristicValue,        // 写入蓝牙特征值
    closeBluetoothAdapter,              // 关闭蓝牙适配器
    setFilterName,                      // 返回 setFilterName 方法
    sendWifiFrameToModule,
    buildWifiFrame,
    resetState,
  };
});

